/* Bir veritabanı nesnesinin, veritabanında kaydedilmesi (save veyâ persist veyâ merge)
 * veritabanından silinmesi (delete) veyâ bu nesnenin günvellenmesi için,
 * en tepedeki generic sınıftır.
 *
 * @author Murat Hunoglu
 */

package com.egitim.model;

import java.lang.reflect.ParameterizedType;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

 


 

/**
 * 
 *  @author Murat Hunoglu
 * 
 @Named
 * @ConversationScoped
 * @Stateful
 */

@Dependent
public abstract class EntityHome<T extends BaseEntity> {

	@Inject
	private Conversation conversation;
	@PersistenceContext(type=PersistenceContextType.EXTENDED)
	private EntityManager em;
	private Long id;
	private T instance;

	public EntityHome() {
	}

	public EntityManager getEm() {
		return em;
	}

	public T getInstance() {
		if (instance == null) {
			if (id != null) {
				instance = loadInstance();
			} else {
				instance = createInstance();
			}
		}
		return instance;
	}

	public void setInstance(T instance) {
		this.instance = instance;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public T loadInstance() {
		return em.find(getClassType(), getId());
	}

	public T createInstance() {
		try {
			return getClassType().newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean isManaged() {
		return getInstance().getId() != null;
	}

	public String save() {
		 
		em.merge(instance);
			 
		 return "saved";
	}
	public String merge() {
		 
		em.merge(instance);
	   return "saved";
   }
	public String cancel() {
		endConversation();
		return "cancelled";
	}

	public String delete() {
		em.remove(em.merge(instance));
	 
		endConversation();
		return "deleted";
	}

	public void initConversation() {
		if (conversation.isTransient()) {
			conversation.begin();
		}
	}

	public void endConversation() {
		try {
			if (!conversation.isTransient()) {
				conversation.end();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}

	}

	// Works on classes extending this class
	@SuppressWarnings("unchecked")
	private Class<T> getClassType() {
		return (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

}